﻿using IceDog.HiDocs.Models;
using IceDog.RabbitMQ.ConfigurationService.Factories;
using Newtonsoft.Json;
using RabbitMQ.Client;
using RabbitMQ.Client.Exceptions;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace IceDog.HiDocs.Publisher
{
    public static class MainApplication
    {
        private static IConnection _connection;
        private static IModel _channel;
        private static int _interval = 1; //消息发送间隔
        private static bool isExit = false;

        //频道名
        private static string exchangeName = "hidocs.exchange";

        public static void Run()
        {
            BeforeStart();
            Setup();
            RunMainLoop();
        }
        private static void BeforeStart()
        {
            Console.Clear();
            Console.WriteLine("Server start");
            for (int i = 3; i > 0; i--)
            {
                Console.WriteLine(i);
                Thread.Sleep(1000);
            }
            Console.WriteLine("Server is starting");
        }
        private static void RunMainLoop()
        {
            while (!isExit)
            {
                ShowMenu();
                var args = GetArgs();
                string cmd = args[0];
                switch (cmd)
                {
                    case "exit":
                        Close();
                        isExit = true;
                        break;
                    case "quit":
                        Close();
                        isExit = true;
                        break;
                    case "send":
                        int count = 1;
                        if (args.Length > 1)
                        {
                            int.TryParse(args[1], out count);
                        }
                        Send(count);
                        break;
                    case "interval":
                        if (args.Length > 1)
                        {
                            int.TryParse(args[1], out _interval);
                        }
                        break;
                    case "clear":
                        Console.Clear();
                        break;
                    default:
                        break;
                }
            }
            Console.WriteLine("Goodbye!");
        }
        private static void ShowMenu()
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("-按照如下形式输入指令:");
            sb.AppendLine("- send 1");
            sb.AppendLine("- interval 2");
            sb.AppendLine("- clear");
            sb.AppendLine("- exit(quit)");
            Console.WriteLine(sb.ToString());
        }

        private static string[] GetArgs()
        {
            var args = Console.ReadLine().ToLowerInvariant()
                .Split(' ', StringSplitOptions.RemoveEmptyEntries);
            return args;
        }
        /// <summary>
        /// 日期推送
        /// </summary>
        private static void Setup()
        {
            try
            {

                var connectionFactory = FactoryProvider.GetDocRMQFactory();
                _connection = connectionFactory.CreateConnection("hidocs.connection");
                _connection.ConnectionShutdown += (object sender, ShutdownEventArgs e) => Console.WriteLine("连接已关闭，原因是：" + e.ReplyText);
                _channel = _connection.CreateModel();
                //创建一个新的，持久的交换区
                _channel.ExchangeDeclare(exchangeName, ExchangeType.Direct, true, false, null);
                Console.WriteLine("设置结束");
            }
            catch (BrokerUnreachableException ex)
            {
                Console.WriteLine("ERROR: RabbitMQ服务器未启动！");
                throw;
            }
        }

        public static void Send(int msgCount)
        {
            for (int i = 1; i <= msgCount; i++)
            {
                var m = new MessageModel()
                {
                    Author = "naka",
                    Title = "测试文档" + i,
                    DocType = (DocumentType)((i % 3)+1)
                };
                var message = JsonConvert.SerializeObject(m);
                byte[] body = Encoding.UTF8.GetBytes(message);
                try
                {
                    var routingKey = "hidocs.routingKey";
                    _channel.BasicPublish(exchange:exchangeName, routingKey: routingKey, basicProperties:_channel.CreateBasicProperties(), body:body);
                }
                catch (AlreadyClosedException ex)
                {
                    Console.WriteLine("ERROR: " + ex.Message);
                    break;
                }

                if (_interval > 0)
                {
                    Thread.Sleep(_interval * 1000);
                }
            }
        }

        private static void Close()
        {
            if (_channel != null && _channel.IsOpen)
            {
                _channel.Close();
            }

            if (_connection != null && _connection.IsOpen)
            {
                _connection.Close();
            }
        }
    }
}
